Skip to content

feat(web): pull request files can be marked as viewed - #7721

Open
yordis wants to merge 14 commits into
pingdotgg:mainfrom
TrogonStack:yordis/feat-pr-files-viewed-upstream
Open

feat(web): pull request files can be marked as viewed#7721
yordis wants to merge 14 commits into
pingdotgg:mainfrom
TrogonStack:yordis/feat-pr-files-viewed-upstream

Conversation

@yordis

@yordis yordis commented Aug 20, 2026

Copy link
Copy Markdown
Contributor
  • A review spread over an afternoon, or picked up on a second machine, starts again from the top every time, so large changes get read in the browser and only small ones stay here.
  • The marks are the host's rather than ours: a checkbox only this app remembers is worse than none, because it looks like the one GitHub shows, disagrees with it, and leaves a reviewer unsure which of the two knows what they have actually read.
  • Declared per provider, so GitHub offers it and the hosts with no equivalent hide the control rather than showing one that cannot keep its promise.
  • Read apart from the patch, because viewed state moves on every press and a patch moves only when somebody pushes; sharing one read would mean either re-fetching a three-hundred-file diff per checkbox or showing a reader their own last press as stale.

Note

Medium Risk
New orchestration RPCs and GitHub GraphQL read/write paths with separate caching; mistakes could desync UI from GitHub or over-fetch, but scope is PR review UX rather than auth or data integrity.

Overview
Adds GitHub-only “viewed file” tracking for pull request reviews: readers can tick files in the Code tab, see a viewed count, and get a Changed hint when GitHub reports the file moved after it was marked viewed. State is stored on the host (not local-only) and is gated by a new viewedFiles capability so other providers hide the control.

Backend: New pullRequests.filesViewed / pullRequests.setFilesViewed RPCs (read vs operate auth), contract types (PullRequestFileViewedState, batch set input), and PullRequestService methods with a dedicated 15s cache and filesViewedEpoch invalidation so ticking files does not drop the diff cache. GitHub reads paginate GraphQL file viewerViewedState (cap 5 pages, truncated flag); writes batch markFileAsViewed / unmarkFileAsViewed in one mutation with paths as variables.

Web: usePullRequestFilesViewed loads host state, optimistic overlay, 400ms debounced batched writes, serial commands per PR, and revert-on-error; PullRequestCodeTab adds per-file checkboxes (fold on mark viewed), meta count, and refresh resets diff + viewed state together.

Reviewed by Cursor Bugbot for commit 3c279bf. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add per-file 'Viewed' marking for pull requests in Code tab

  • Adds full-stack support for reading and toggling per-file viewed state on GitHub pull requests, including new contracts (PullRequestFileViewedState, PullRequestFilesViewedResult, PullRequestSetFilesViewedInput), WebSocket RPCs (pullRequests.filesViewed, pullRequests.setFilesViewed), and server-side GitHub GraphQL queries/mutations with pagination capped at 5 pages
  • Introduces usePullRequestFilesViewed hook with optimistic UI overlay, 400ms debounced batch writes, overlapping-request tracking, and toast on failure; integrates a 'Viewed'/'Changed' checkbox into file headers in PullRequestCodeTab.tsx that folds/unfolds the file diff to match viewed state
  • Server caches filesViewed results (128 entries, 15s TTL) with a separate epoch so setFilesViewed invalidates only the viewed-files cache without touching the diff cache; capability gating via viewedFiles flag on PullRequestCapabilities
  • Risk: setFilesViewed on GitHub builds a single batched GraphQL mutation with aliased markFileAsViewed/unmarkFileAsViewed operations; if GitHub rejects aliased batch mutations beyond a size limit, large PRs may fail silently — verify buildSetFilesViewedGraphQlMutation in gitHubPullRequestJson.ts handles GitHub's mutation alias limits

Macroscope summarized 3c279bf.

@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ecb25414-5483-404d-9d82-584a9879d762

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Aug 20, 2026

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the changed web UI: the new viewed-file checkbox in the diff header, the counter in the toolbar, and the fold/overlay logic modules. Two findings, both on changed lines in PullRequestCodeTab.tsx.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/pullRequest/PullRequestCodeTab.tsx
Comment thread apps/web/src/components/pullRequest/PullRequestCodeTab.tsx Outdated
Comment thread apps/web/src/components/pullRequest/usePullRequestFilesViewed.ts Outdated
Comment thread apps/server/src/sourceControl/githubGraphQlBudget.ts Outdated
Comment thread apps/web/src/components/pullRequest/usePullRequestFilesViewed.ts Outdated
Comment thread apps/web/src/components/pullRequest/PullRequestCodeTab.tsx
Comment thread apps/web/src/components/pullRequest/usePullRequestFilesViewed.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a substantial GitHub-only review workflow spanning the UI, client/server RPCs, caching and concurrency, and external GraphQL mutations. It also changes authorization code, so the breadth and sensitivity of the runtime path warrant human review.

You can add or adjust custom eligibility rules. Learn more.

Comment thread apps/web/src/components/pullRequest/PullRequestCodeTab.tsx
Comment thread apps/server/src/sourceControl/githubGraphQlBudget.ts Outdated
Comment thread apps/web/src/components/pullRequest/usePullRequestFilesViewed.ts Outdated

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the web UI changes (PullRequestCodeTab.tsx, pullRequestDiff.logic.ts, pullRequestFilesViewed.logic.ts, usePullRequestFilesViewed.ts) for shared-primitive use, Tailwind/CSS ownership and virtualizer behavior.

Both findings from the previous run are resolved: the Checkbox no longer carries a partial size-* override, and truncated is now threaded through the hook and surfaced in the meta line with the same Tooltip + TriangleAlertIcon treatment the withheld-diff caveat uses. Two remaining items below — one virtualizer regression risk, one accessible-name issue on the new control.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/pullRequest/PullRequestCodeTab.tsx Outdated
Comment thread apps/web/src/components/pullRequest/PullRequestCodeTab.tsx
yordis added 10 commits August 20, 2026 18:06
A review spread over an afternoon, or picked up on a second machine, started
again from the top every time, so large changes were read in the browser and
only small ones stayed here.

The marks are the host's rather than ours because a checkbox only this app
remembers is worse than none: it looks like the one GitHub shows, disagrees
with it, and leaves a reviewer unsure which of the two knows what they have
actually read.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
…he window resets

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
…since

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
…at it is partial

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
…he wrong way

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
…count

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
…carries

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
A press moved the whole viewed view, and every file header on screen was memoized on it, so one tick cost a rebuild of all of them. The same mark also has to say whether the control is offered at all, or a capability arriving after the first paint leaves the headers without a box.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
It borrowed its name from the label beside it, and that label turns into "Changed" once the file has been pushed to, leaving a reader who cannot see it with no idea what the box does.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis
yordis force-pushed the yordis/feat-pr-files-viewed-upstream branch from 1296cb6 to 6b44e51 Compare August 20, 2026 22:07
@yordis

yordis commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author
Screen.Recording.2026-08-20.at.6.15.29.PM.mov

The branch had drifted behind main far enough to conflict, which blocked
review of the change itself.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 28eea17. Configure here.

Comment thread apps/web/src/components/pullRequest/PullRequestCodeTab.tsx
The button exists for a reader who can see that what they are looking at is
behind, so leaving one part of the page on the last read defeats the point of
pressing it. A push since that read is exactly when the mark beside a ticked
file stops being true.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Comment thread apps/web/src/components/pullRequest/usePullRequestFilesViewed.ts Outdated
An error the reader cannot act on, about a press they have already replaced,
reads as their current tick having been lost when it has not.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

@macroscopeapp macroscopeapp Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One finding on the new viewed-files hook: the command-failure path surfaces an error toast for interrupt-only failures, which diverges from the repo's established useAtomCommand failure convention. Everything else in the web scope (Checkbox/Tooltip primitive use, the amber caveat icon matching the adjacent meta-line pattern, header portal render-prop stability via refs, explicit environmentId threading) looks consistent.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/pullRequest/usePullRequestFilesViewed.ts
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant